import { defineConfig, normalizePath } from 'vite';
import { readFileSync } from 'node:fs';
import { resolve } from 'path';
import merge from 'lodash-es/merge.js';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import viteCompression from 'vite-plugin-compression';
// import postcssPresetEnv from 'postcss-preset-env';
import copy from './vite-plugin-copy.js';
import vueDevTools from 'vite-plugin-vue-devtools';
import { VitePluginEnv, getEnv } from './vite-plugin-env.js';
import { PREFIX_FILE_SERVE, PREFIX_MICRO_SERVE } from './config/index.js';

function pickValue(options, key) {
  const value = options[key];
  delete options[key];
  return value;
}

function useCopyWebrtcIframe({ __dirname, config, env }) {
  if (env.PROD === true) {
    config.plugins.push(
      copy({
        targets: [
          {
            src: normalizePath(resolve(__dirname, './', 'node_modules/@gis/lib/components/tx-webrtc/iframe')),
            dest: normalizePath(
              resolve(__dirname, './', config.build.outDir + '/node_modules/@gis/lib/components/tx-webrtc/iframe')
            ),
          },
        ],
      })
    );
  }
}

function useCopyMarkerIcon({ __dirname, config, env }) {
  if (env.PROD === true) {
    config.plugins.push(
      copy({
        targets: [
          {
            src: normalizePath(resolve(__dirname, './', 'node_modules/@gis/modules/components/gis-map/assets/marker')),
            dest: normalizePath(resolve(__dirname, './', config.build.outDir + '/assets/marker')),
          },
          {
            src: normalizePath(
              resolve(__dirname, './', 'node_modules/@gis/modules/components/gis-map/assets/marker-legend')
            ),
            dest: normalizePath(resolve(__dirname, './', config.build.outDir + '/assets/marker-legend')),
          },
        ],
      })
    );
  }
}

export function getViteConfigure(mode, config, handleConfig) {
  config = Object.assign({}, config);
  const __dirname = pickValue(config, '__dirname');
  const process = pickValue(config, 'process');
  const vuePluginOption = pickValue(config, 'vuePluginOption');
  const useWebrtc = pickValue(config, 'useWebrtc');
  const useCopyMarkerIcons = pickValue(config, 'useCopyMarkerIcons');

  const certOptions = {
    key: readFileSync(resolve(__dirname, 'node_modules/@gis/lib/cert/server.key'), 'utf8'),
    cert: readFileSync(resolve(__dirname, 'node_modules/@gis/lib/cert/server.crt'), 'utf8'),
  };
  const env = getEnv({ __dirname: __dirname, mode: mode });
  console.log('env: ', env);
  const defaultConfig = {
    envPrefix: env.ENV_PREFIX,
    base: '/' + env.PROJECT_NAME,
    build: {
      outDir: './' + env.PROJECT_NAME,
      chunkSizeWarningLimit: 500,
      assetsInlineLimit: 4096,
      minify: true,
    },
    esbuild: {
      drop: ['console'],
    },
    optimizeDeps: {
      force: true,
      esbuildOptions: {
        loader: { '.js': 'jsx' },
      },
    },
    css: {
      preprocessorOptions: {
        less: {
          javascriptEnabled: true,
        },
        scss: {
          // 引入 mixin.scss 这样就可以在全局中使用 var.scss中预定义的变量了
          // additionalData: '@import "node_modules/@gis/lib/style/var.scss";',
        },
      },
      postcss: {
        plugins: [
          // postcssPresetEnv({
          //   // 就是让postcss知道有一些全局变量需要记录下来 ，包含postcss-custom-properties用于处理css变量
          //   importFrom: path.resolve(__dirname, './variable.css'),
          // }),
        ],
      },
    },
    plugins: [
      VitePluginEnv({ __dirname: __dirname, mode: mode }),
      vue(vuePluginOption),
      vueJsx({ include: /\.[jt]sx?$/ }),
      // 打包压缩，主要是本地gzip，如果服务器配置压缩也可以
      viteCompression({
        verbose: true, // 是否在控制台中输出压缩结果
        disable: false,
        threshold: 102400, // 如果体积大于阈值，将被压缩，单位为b，体积过小时请不要压缩，以免适得其反
        algorithm: 'gzip', // 压缩算法，可选['gzip'，' brotliccompress '，'deflate '，'deflateRaw']
        ext: '.gz',
        deleteOriginFile: false, // 源文件压缩后是否删除
      }),
      vueDevTools(),
    ],
    resolve: {
      alias: {
        '@': resolve(__dirname, 'src'),
        '~@': resolve(__dirname, 'src'),
        '@gis/lib': resolve(__dirname, 'node_modules/@gis/lib'),
        '@gis/modules': resolve(__dirname, 'node_modules/@gis/modules'),
      },
    },
    server: {
      https: certOptions,
      host: true,
      proxy: {
        [`^${env.VUE_APP_API_BASE_URL}/`]: {
          target: env.VUE_APP_API_AGENT_URL,
          changeOrigin: true,
          rewrite: (path) => path.replace(new RegExp('^' + env.VUE_APP_API_BASE_URL), ''),
        },
        [`^${env.VUE_APP_MAP_BASE_URL}/`]: {
          target: env.VUE_APP_MAP_AGENT_URL,
          ws: true,
          changeOrigin: true,
          rewrite: (path) => path.replace(new RegExp('^' + env.VUE_APP_MAP_BASE_URL), ''),
        },
      },
    },
    preview: {
      cors: true,
      https: certOptions,
      strictPort: true,
      proxy: {
        ['^' + PREFIX_MICRO_SERVE + '/']: {
          target: env.VUE_APP_API_AGENT_URL,
          changeOrigin: true,
        },
        ['^' + PREFIX_FILE_SERVE + '/']: {
          target: env.VUE_APP_API_AGENT_URL,
          changeOrigin: true,
        },
      },
    },
  };
  config = merge(defaultConfig, config);
  if (typeof handleConfig === 'function') {
    handleConfig({ env, mode, config });
  }
  if (useCopyMarkerIcons === true) {
    useCopyMarkerIcon({ __dirname, config, env });
  }
  if (useWebrtc === true) {
    useCopyWebrtcIframe({ __dirname, config, env });
  }
  // console.log('config: ', config);
  return config;
}

export default function getViteConfig(config, handleConfig) {
  return defineConfig(({ mode }) => {
    return getViteConfigure(mode, config, handleConfig);
  });
}
